"use strict";

const DbMixin = require("../mixins/db.mixin");

/**
 * @typedef {import('moleculer').ServiceSchema} ServiceSchema Moleculer's Service Schema
 * @typedef {import('moleculer').Context} Context Moleculer's Context
 */

/** @type {ServiceSchema} */
module.exports = {
    name: "blog",

    /**
     * Mixins
     */
    mixins: [DbMixin("blog")],

    /**
     * Settings
     */
    settings: {
        // Available fields in the responses
        fields: [
            "_id",
            "title",
            "summary",
            "excerpt",
            "date",
            "publishDate",
            "category",
            "tags",
            "content",
            "status",
            "createdAt",
            "updatedAt",
            "contentHtml",
            "views",
            "readTime",
            "coverImage",
            "author"
        ]
    },

    /**
     * Dependencies
     */
    dependencies: ["categories", "tags", "settings"],

    /**
     * Actions
     */
    actions: {
        // --- BLOG API ACTIONS ---

        /**
         * Get articles list
         */
        getArticles: {
            rest: "GET /articles",
            cache: false,
            async handler(ctx) {
                const { category, tag, page = 1, pageSize = 10 } = ctx.params;

                try {
                    this.logger.debug(`获取文章列表, 参数: ${JSON.stringify(ctx.params)}`);
                    // 构建查询条件
                    const query = {};

                    // public 接口只显示已发布的文章
                    query.status = "published";

                    if (category) {
                        query.category = category;
                    }
                    if (tag) {
                        // tags 是数组字段，需要使用 $in 操作符匹配
                        query.tags = { $in: [tag] };
                    }

                    this.logger.debug(`查询条件: ${JSON.stringify(query)}`);

                    // 分页设置
                    const skip = (page - 1) * pageSize;

                    // 从数据库查询文章列表
                    const [articles, total] = await Promise.all([
                        this.adapter.find({
                            query,
                            limit: pageSize,
                            offset: skip,
                            sort: { date: -1 } // 按日期降序排序
                        }),
                        this.adapter.count(query)
                    ]);
                    // 获取所有分类和标签信息用于映射
                    const [categories, tags] = await Promise.all([
                        ctx.call("categories.find", {}, { meta: { $cache: false } }),
                        ctx.call("tags.find", {}, { meta: { $cache: false } })
                    ]);

                    // 创建分类和标签的映射
                    const categoryMap = {};
                    categories.forEach(cat => {
                        categoryMap[cat._id.toString()] = {
                            id: cat._id.toString(),
                            name: cat.name
                        };
                    });

                    const tagMap = {};
                    tags.forEach(tag => {
                        tagMap[tag._id.toString()] = {
                            id: tag._id.toString(),
                            name: tag.name
                        };
                    });
                    // 格式化数据，确保与API文档一致
                    const formattedArticles = articles.map(article => ({
                        _id: article._id.toString(),
                        title: article.title,
                        summary: article.summary,
                        excerpt: article.excerpt,
                        status: article.status || 'draft',
                        date: article.date,
                        publishDate: article.publishDate ? new Date(article.publishDate).toLocaleString('zh-CN', {
                            year: 'numeric',
                            month: '2-digit',
                            day: '2-digit',
                            hour: '2-digit',
                            minute: '2-digit',
                            second: '2-digit'
                        }) : null,
                        category: article.category ? categoryMap[article.category] || { id: article.category, name: '未分类' } : null,
                        tags: article.tags.map(tag => tagMap[tag] || { id: tag, name: '未知' }),
                        views: article.views || 0,
                        readTime: article.readTime || 5, // 默认阅读时间5分钟
                        coverImage: article.coverImage || null,
                        author: article.author || "Gulu" // 默认作者
                    }));
                    return {
                        code: 200,
                        data: {
                            list: formattedArticles,
                            total,
                            page: parseInt(page),
                            pageSize: parseInt(pageSize)
                        },
                        message: "success"
                    };
                } catch (error) {
                    this.logger.error(`获取文章列表失败: ${error.message}`, error);
                    return {
                        code: 500,
                        data: null,
                        message: "服务器内部错误"
                    };
                }
            }
        },

        /**
         * Get articles for admin (all status)
         */
        getAdminArticles: {
            cache: false,
            async handler(ctx) {
                const { category, tag, page = 1, pageSize = 10, status } = ctx.params;

                try {
                    this.logger.debug(`获取管理员文章列表, 参数: ${JSON.stringify(ctx.params)}`);
                    // 构建查询条件
                    const query = {};

                    // admin 接口可以根据 status 参数过滤，如果没有 status 参数则显示所有状态
                    if (status) {
                        query.status = status;
                    }

                    if (category) {
                        query.category = category;
                    }
                    if (tag) {
                        // tags 是数组字段，需要使用 $in 操作符匹配
                        query.tags = { $in: [tag] };
                    }

                    this.logger.debug(`管理员查询条件: ${JSON.stringify(query)}`);

                    // 分页设置
                    const skip = (page - 1) * pageSize;

                    // 从数据库查询文章列表
                    const [articles, total] = await Promise.all([
                        this.adapter.find({
                            query,
                            limit: pageSize,
                            offset: skip,
                            sort: { date: -1 } // 按日期降序排序
                        }),
                        this.adapter.count(query)
                    ]);
                    // 获取所有分类和标签信息用于映射
                    const [categories, tags] = await Promise.all([
                        ctx.call("categories.find", {}, { meta: { $cache: false } }),
                        ctx.call("tags.find", {}, { meta: { $cache: false } })
                    ]);

                    // 创建映射对象
                    const categoryMap = {};
                    const tagMap = {};

                    categories.forEach(cat => {
                        categoryMap[cat._id.toString()] = cat;
                    });

                    tags.forEach(tag => {
                        tagMap[tag._id.toString()] = tag;
                    });

                    // 格式化文章数据
                    const formattedArticles = articles.map(article => ({
                        _id: article._id.toString(),
                        title: article.title,
                        summary: article.summary,
                        excerpt: article.excerpt,
                        date: article.date,
                        publishDate: article.publishDate ? new Date(article.publishDate).toLocaleString('zh-CN', {
                            year: 'numeric',
                            month: '2-digit',
                            day: '2-digit',
                            hour: '2-digit',
                            minute: '2-digit',
                            second: '2-digit'
                        }) : null,
                        status: article.status || 'draft',
                        category: categoryMap[article.category] ? {
                            id: categoryMap[article.category]._id.toString(),
                            name: categoryMap[article.category].name
                        } : null,
                        tags: article.tags ? article.tags.map(tagId => {
                            const tag = tagMap[tagId.toString()];
                            return tag ? {
                                id: tag._id.toString(),
                                name: tag.name
                            } : null;
                        }).filter(Boolean) : [],
                        views: article.views || 0,
                        readTime: article.readTime || 5,
                        coverImage: article.coverImage || null,
                        author: article.author || "Gulu",
                        createdAt: article.createdAt ? new Date(article.createdAt).toLocaleString('zh-CN', {
                            year: 'numeric',
                            month: '2-digit',
                            day: '2-digit',
                            hour: '2-digit',
                            minute: '2-digit',
                            second: '2-digit'
                        }) : null,
                        updatedAt: article.updatedAt ? new Date(article.updatedAt).toLocaleString('zh-CN', {
                            year: 'numeric',
                            month: '2-digit',
                            day: '2-digit',
                            hour: '2-digit',
                            minute: '2-digit',
                            second: '2-digit'
                        }) : null
                    }));

                    return {
                        code: 200,
                        data: {
                            list: formattedArticles,
                            total,
                            page,
                            pageSize
                        },
                        message: "success"
                    };
                } catch (error) {
                    this.logger.error(`获取管理员文章列表失败: ${error.message}`, error);
                    return {
                        code: 500,
                        data: null,
                        message: "服务器内部错误"
                    };
                }
            }
        },

        /**
         * Get article detail
         */
        getArticleDetail: {
            rest: "GET /articles/:id",
            params: {
                id: "string"
            },
            cache: false,
            async handler(ctx) {
                const { id } = ctx.params;

                try {
                    this.logger.debug(`获取文章详情: ${id}`);
                    // 从数据库查询文章详情
                    let article = await this.adapter.findById(id);

                    if (!article) {
                        return {
                            code: 404,
                            data: null,
                            message: "文章不存在"
                        };
                    }

                    // public 接口只能访问已发布的文章
                    if (article.status !== "published") {
                        return {
                            code: 404,
                            data: null,
                            message: "文章不存在"
                        };
                    }

                    // 更新浏览量
                    article.views = (article.views || 0) + 1;
                    await this.adapter.updateById(id, { $set: { views: article.views } });
                    // 获取分类信息
                    let categoryInfo = null;
                    if (article.category) {
                        try {
                            categoryInfo = await ctx.call("categories.get", { id: article.category });
                        } catch (error) {
                            this.logger.warn(`获取分类信息失败: ${error.message}`);
                        }
                    }

                    // 获取标签信息
                    let tagsInfo = [];
                    if (article.tags && article.tags.length > 0) {
                        try {
                            const tagPromises = article.tags.map(tagId =>
                                ctx.call("tags.get", { id: tagId }).catch(error => {
                                    this.logger.warn(`获取标签信息失败: ${error.message}`);
                                    return null;
                                })
                            );
                            const tags = await Promise.all(tagPromises);
                            tagsInfo = tags.filter(tag => tag !== null);
                        } catch (error) {
                            this.logger.warn(`获取标签信息失败: ${error.message}`);
                        }
                    }
                    // 格式化基本文章数据，确保与API文档一致
                    const formattedArticle = {
                        _id: article._id.toString(),
                        title: article.title,
                        summary: article.summary,
                        excerpt: article.excerpt,
                        content: article.content,
                        contentHtml: article.contentHtml || '',
                        date: article.date,
                        publishDate: article.publishDate ? new Date(article.publishDate).toLocaleString('zh-CN', {
                            year: 'numeric',
                            month: '2-digit',
                            day: '2-digit',
                            hour: '2-digit',
                            minute: '2-digit',
                            second: '2-digit'
                        }) : null,
                        status: article.status || 'draft',
                        category: categoryInfo ? {
                            _id: categoryInfo._id.toString(),
                            id: categoryInfo._id.toString(),
                            name: categoryInfo.name,
                            description: categoryInfo.description
                        } : null,
                        tags: tagsInfo.map(tag => ({
                            _id: tag._id.toString(),
                            id: tag._id.toString(),
                            name: tag.name,
                            description: tag.description
                        })),
                        views: article.views || 0,
                        readTime: article.readTime || 5,
                        coverImage: article.coverImage || null,
                        author: article.author || "Gulu", // 默认作者
                        createdAt: article.createdAt ? new Date(article.createdAt).toLocaleString('zh-CN', {
                            year: 'numeric',
                            month: '2-digit',
                            day: '2-digit',
                            hour: '2-digit',
                            minute: '2-digit',
                            second: '2-digit'
                        }) : null,
                        updatedAt: article.updatedAt ? new Date(article.updatedAt).toLocaleString('zh-CN', {
                            year: 'numeric',
                            month: '2-digit',
                            day: '2-digit',
                            hour: '2-digit',
                            minute: '2-digit',
                            second: '2-digit'
                        }) : null
                    };

                    // 获取上一篇和下一篇文章（只显示已发布的）
                    const prevArticle = await this.adapter.findOne({
                        date: { $lt: article.date },
                        status: "published"
                    }, {
                        fields: ["_id", "title"],
                        sort: { date: -1 },
                        limit: 1
                    });

                    const nextArticle = await this.adapter.findOne({
                        date: { $gt: article.date },
                        status: "published"
                    }, {
                        fields: ["_id", "title"],
                        sort: { date: 1 },
                        limit: 1
                    });

                    // 获取相关文章（同分类的其他已发布文章）
                    const relatedArticles = await this.adapter.find({
                        query: {
                            category: article.category,
                            _id: { $ne: article._id },
                            status: "published"
                        },
                        fields: ["_id", "title", "summary", "date", "views"],
                        limit: 3,
                        sort: { date: -1 }
                    });

                    // 添加关联数据
                    formattedArticle.prevArticle = prevArticle ? {
                        id: prevArticle._id.toString(),
                        title: prevArticle.title,
                        url: `/article/${prevArticle._id.toString()}`
                    } : null;

                    formattedArticle.nextArticle = nextArticle ? {
                        id: nextArticle._id.toString(),
                        title: nextArticle.title,
                        url: `/article/${nextArticle._id.toString()}`
                    } : null;

                    formattedArticle.relatedArticles = relatedArticles.map(related => ({
                        id: related._id.toString(),
                        title: related.title,
                        summary: related.summary,
                        date: related.date,
                        views: related.views || 0
                    }));

                    return {
                        code: 200,
                        data: formattedArticle,
                        message: "success"
                    };
                } catch (error) {
                    this.logger.error(`获取文章详情失败: ${error.message}`, error);
                    return {
                        code: 500,
                        data: null,
                        message: "服务器内部错误"
                    };
                }
            }
        },

        /**
         * 获取文章详情 - Admin版本（可获取任何状态的文章）
         */
        getAdminArticleDetail: {
            params: {
                id: "string"
            },
            cache: false,
            async handler(ctx) {
                try {
                    const { id } = ctx.params;
                    this.logger.info(`获取文章详情: ${id}`);

                    // 获取文章基本信息（不检查状态）
                    const article = await this.adapter.findById(id);
                    if (!article) {
                        return {
                            code: 404,
                            data: null,
                            message: "文章不存在"
                        };
                    }

                    // 获取分类信息
                    let categoryInfo = null;
                    if (article.category) {
                        try {
                            categoryInfo = await ctx.call("categories.get", { id: article.category });
                        } catch (error) {
                            this.logger.warn(`获取分类信息失败: ${error.message}`);
                        }
                    }

                    // 获取标签信息
                    let tagsInfo = [];
                    if (article.tags && article.tags.length > 0) {
                        try {
                            const tagPromises = article.tags.map(tagId =>
                                ctx.call("tags.get", { id: tagId }).catch(error => {
                                    this.logger.warn(`获取标签信息失败: ${error.message}`);
                                    return null;
                                })
                            );
                            const tags = await Promise.all(tagPromises);
                            tagsInfo = tags.filter(tag => tag !== null);
                        } catch (error) {
                            this.logger.warn(`获取标签信息失败: ${error.message}`);
                        }
                    }

                    // 格式化文章数据
                    const formattedArticle = {
                        _id: article._id.toString(),
                        id: article._id.toString(),
                        title: article.title,
                        summary: article.summary,
                        content: article.content,
                        contentHtml: article.contentHtml || '',
                        category: categoryInfo ? {
                            _id: categoryInfo._id.toString(),
                            id: categoryInfo._id.toString(),
                            name: categoryInfo.name,
                            description: categoryInfo.description
                        } : null,
                        tags: tagsInfo.map(tag => ({
                            _id: tag._id.toString(),
                            id: tag._id.toString(),
                            name: tag.name,
                            description: tag.description
                        })),
                        status: article.status || 'draft',
                        date: article.date,
                        publishDate: article.publishDate,
                        views: article.views || 0,
                        readTime: article.readTime || 0,
                        coverImage: article.coverImage || '',
                        author: article.author || '',
                        createdAt: article.createdAt,
                        updatedAt: article.updatedAt
                    };

                    return {
                        code: 200,
                        data: formattedArticle,
                        message: "success"
                    };
                } catch (error) {
                    this.logger.error(`获取文章详情失败: ${error.message}`, error);
                    return {
                        code: 500,
                        data: null,
                        message: "获取文章详情失败"
                    };
                }
            }
        },

        /**
         * Get personal info
         */
        getPersonalInfo: {
            rest: "GET /personal-info",
            cache: false,
            async handler(ctx) {
                try {
                    this.logger.debug('获取个人信息');
                    // 从 settings 服务获取个人信息
                    const settings = await ctx.call("settings.getAll", {}, { meta: { $cache: false } });

                    // 提取所有以 personal. 开头的设置
                    const personalSettings = {};
                    if (settings.data && typeof settings.data === 'object') {
                        for (const [key, value] of Object.entries(settings.data)) {
                            if (key.startsWith('personal.')) {
                                const personalKey = key.replace('personal.', '');
                                personalSettings[personalKey] = value;
                            }
                        }
                    }

                    // 如果没有个人信息设置，则使用默认值
                    const personalInfo = {
                        name: personalSettings.name || "Gulu Blog",
                        title: personalSettings.title || "前端开发工程师",
                        description: personalSettings.description || "专注于Vue.js生态系统开发，热衷于分享前端技术和最佳实践。",
                        initials: personalSettings.initials || "GB",
                        avatar: personalSettings.avatar || "",
                        about: personalSettings.about || [
                            "你好！我是一名充满热情的前端开发工程师，拥有多年的Web开发经验。我专注于使用现代前端技术构建高质量、高性能的Web应用。",
                            "我热衷于学习新技术，并将其应用到实际项目中。同时，我也喜欢通过写作分享我的知识和经验，希望能够帮助到更多的开发者。",
                            "在这个博客中，我会分享关于前端开发的各种知识，包括Vue.js、React、TypeScript、性能优化方面的内容。"
                        ],
                        aboutHtml: personalSettings.aboutHtml || "",
                        contact: personalSettings.contactMethods.map(method => ({
                            ...method,
                            type: method.type,
                            label: method.label,
                            value: method.value,
                            href: method.value
                        })) || [
                                {
                                    type: "email",
                                    label: "邮箱",
                                    value: "contact@gulublog.com",
                                    href: "mailto:contact@gulublog.com"
                                },
                                {
                                    type: "github",
                                    label: "GitHub",
                                    value: "github.com/gulublog",
                                    href: "https://github.com/gulublog"
                                }
                            ]
                    };

                    return {
                        code: 200,
                        data: personalInfo,
                        message: "success"
                    };
                } catch (error) {
                    this.logger.error(`获取个人信息失败: ${error.message}`, error);
                    return {
                        code: 500,
                        data: null,
                        message: "服务器内部错误: " + error.message
                    };
                }
            }
        },

        /**
         * Update personal info
         */
        updatePersonalInfo: {
            rest: "PUT /personal-info",
            params: {
                name: "string|optional",
                title: "string|optional",
                description: "string|optional",
                initials: "string|optional",
                about: "array|optional",
                skills: "array|optional",
                contact: "object|optional",
                avatar: "string|optional"
            },
            cache: false,  // 完全禁用缓存，写操作不应该被缓存
            async handler(ctx) {
                try {
                    this.logger.debug(`更新个人信息: ${JSON.stringify(ctx.params)}`);
                    // 将个人信息作为设置保存到 settings 服务
                    const updates = {};
                    Object.entries(ctx.params).forEach(([key, value]) => {
                        if (value !== undefined) {
                            updates[`personal.${key}`] = value;
                        }
                    });

                    if (Object.keys(updates).length > 0) {
                        await ctx.call("settings.updateMultiple", { settings: updates }, { meta: { $cache: false } });
                        this.logger.info('个人信息更新成功');
                        return {
                            code: 200,
                            data: ctx.params,
                            message: "个人信息更新成功"
                        };
                    }

                    return {
                        code: 400,
                        data: null,
                        message: "没有提供任何更新信息"
                    };
                } catch (error) {
                    this.logger.error(`更新个人信息失败: ${error.message}`, error);
                    return {
                        code: 500,
                        data: null,
                        message: "更新个人信息失败: " + error.message
                    };
                }
            }
        }
    },

    /**
     * Methods
     */
    methods: {},

    /**
     * Events
     */
    events: {},

    /**
     * Service created lifecycle event handler
     */
    created() { },

    /**
     * Service started lifecycle event handler
     */
    async started() {
        // 禁用自动填充种子数据，所有数据均通过数据库读取
    },

    /**
     * Service stopped lifecycle event handler
     */
    async stopped() { }
};